﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using EfConcurrencyOnAspNetMvc.Models;
using System.Data.Entity.Infrastructure;

namespace EfConcurrencyOnAspNetMvc.Controllers
{
    public class SongController : Controller
    {
        //
        // GET: /Song/

        public ActionResult Index()
        {
            using (var db = new TheMusicContext())
            {
                return View(db.Songs.OrderBy(x => x.SongName).ToList());
            }
        }

        public ViewResult Input(int id = 0)
        {
            using (var db = new TheMusicContext())
            {
                var song = id != 0 ? db.Songs.Find(id) : new Song();
                return View(song);
            }
        }

        public ActionResult Delete(int id, byte[] Version)
        {
            using (var db = new TheMusicContext())
            {

                var stub = new Song { SongId = id, Version = Version };
                if (Request.HttpMethod == "POST")
                {
                    try
                    {                        
                        db.Entry(stub).State = System.Data.EntityState.Deleted;
                        db.SaveChanges();
                        return RedirectToAction("Index");
                    }
                    catch (DbUpdateConcurrencyException ex)
                    {
                        var entry = ex.Entries.Single();
                        var dbValues = entry.GetDatabaseValues();


                        // already deleted
                        if (dbValues == null)
                            return RedirectToAction("Index");
                                         
                        ModelState.AddModelError(string.Empty, "The record you are attempting to delete was modified by other user first. Do you still want to delete this record?");
                        Song songDbValues = (Song)dbValues.ToObject();       

                        return View(songDbValues);
                    }                    
                }
                else
                {
                    var songToDelete = db.Songs.Find(id);
                    return View(songToDelete);
                }
            }
        }


        [HttpPost]
        public ActionResult Save(Song song)
        {
            SaveCommon(song);

            return View("Input", song); // song is the model
        }


        
        private void SaveCommon(Song song)
        {
            using (var db = new TheMusicContext())
            {
                try
                {
                    if (song.SongId == 0)
                        db.Songs.Add(song);                                                
                    else
                        db.Entry(song).State = System.Data.EntityState.Modified;

                    db.SaveChanges();

                    ModelState.Remove("SongId"); // to force ASP.NET MVC to get the SongId value from the model, not from ModelState
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    var entry = ex.Entries.Single();


                    var dbValues = entry.GetDatabaseValues();

                    // already deleted
                    if ( dbValues == null)
                    {
                        ModelState.AddModelError(string.Empty, "This record you are attempting to save is already deleted by other user");
                        return;
                    }

                    
                    Song songDbValues = (Song) dbValues.ToObject();
                    Song userValues = (Song) entry.Entity;



                    if (songDbValues.SongName != userValues.SongName)
                        ModelState.AddModelError("SongName", "Current value made by other user: " + songDbValues.SongName);

                    if (songDbValues.AlbumName != userValues.AlbumName)
                        ModelState.AddModelError("AlbumName", "Current value made by other user: " + songDbValues.AlbumName);

                    ModelState.AddModelError(string.Empty, "The record you attempted to edit was already modified by another user since you last loaded it. Open the latest changes on this record");
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError(string.Empty, ex.Message + "\n" + ex.StackTrace + ex.InnerException.Message);
                }
                
              
            }

                       
        }//SaveCommon



    }//class
}
